using DaprPlus.Filters;
using DaprPlus.MediatR;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.Options;

using Org.BouncyCastle.Ocsp;
using OSharp.Filter;


namespace Liuliu.Fsb.ApiGateway.Controllers;

[ApiResultWrapperFilter]
public class RoleResourceController()
    : ApiControllerBase
{
    [HttpGet("access")]
    [Produces<string[]>]
    public async Task<ActionResult> GetAccessCodes()
    {
        var options = ServiceProvider.GetRequiredService<IOptions<DaprOptions>>().Value;
        var appIds = options.AppIds.Values.ToArray();
        if (appIds.Length == 0)
        {
            return BadRequest(new ApiResult
            {
                ResultType = ApiResultType.Error,
                Message = "服务列表不能为空"
            });
        }
        var requests = appIds.ToDictionary(
            item => item,
            item => ServiceProvider.CreateInvokeMethodRequest(HttpMethod.Get, item, "/api/roleResource/access"));

        var daprClient = ServiceProvider.GetRequiredService<DaprClient>();
        // 创建并执行任务
        var tasks = requests.Select(async r => new
        {
            ServiceName = r.Key,
            Result = await daprClient.InvokeMethodAsync<ApiResult<string[]>>(r.Value)
        });

        var results = await Task.WhenAll(tasks);

        // 合并所有服务返回的权限码并去重
        var allAccessCodes = results
            .Where(r => r.Result.IsSuccess() && r.Result.Data?.Length > 0)
            .SelectMany(r =>
            {
                var codes = new List<string>();
                var data = r.Result.Data ?? [];
                if (data.Any(m => !m.StartsWith("Resource") && !m.StartsWith("RoleResource")))
                {
                    codes.Add(r.ServiceName);
                }
                codes.AddRange(data);
                return codes;
            })
            .Distinct()
            .ToArray();

        return Ok(allAccessCodes);
    }

    [HttpPost("page")]
    [Produces<PageResult<RoleResourceOutDto>>]
    public async Task<ActionResult> GetRoleResourcePage([FromBody] RoleResourcePageQuery query)
    {
        var request = ServiceProvider.CreateInvokeMethodRequest(HttpMethod.Post, query.Service,
            "/api/roleResource/page", query.Query);
        var daprClient = ServiceProvider.GetRequiredService<DaprClient>();
        var result = await daprClient.InvokeMethodAsync<ApiResult<PageResult<RoleResourceOutDto>>>(request);
        return Ok(result);
    }

    [HttpPost("setrole")]
    [Produces<ApiResult>]
    public async Task<ActionResult> SetRoleResource([FromBody] SetRoleResourceRequest request)
    {
        var daprClient = ServiceProvider.GetRequiredService<DaprClient>();
        var tasks = request.Dict.Where(kvp => kvp.Value.Length > 0)
            .Select(kvp => ServiceProvider.CreateInvokeMethodRequest(kvp.Key, "/api/roleResource/setrole",
                new { RoleId = request.RoleId, Dtos = kvp.Value }))
            .Select(req => daprClient.InvokeMethodAsync<ApiResult>(req))
            .ToArray();

        var results = await Task.WhenAll(tasks);

        // 检查所有服务的处理结果
        if (results.Any(r => r.IsError()))
        {
            return BadRequest(new ApiResult
            {
                ResultType = ApiResultType.Error,
                Message = "部分服务授权失败"
            });
        }

        var result = results.All(m => m.IsInfo()) ? ApiResult.Info("角色权限没有变化") : ApiResult.Success("角色授权操作成功");
        return Ok(result);
    }

    [HttpPost("setfilters")]
    [Produces<ApiResult>]
    public async Task<ActionResult> SetFilterGroups([FromBody] SetFilterGroupsRequest request)
    {
        var request2 = ServiceProvider.CreateInvokeMethodRequest(HttpMethod.Post, request.Service,
            "/api/roleResource/setfilters", request);
        var daprClient = ServiceProvider.GetRequiredService<DaprClient>();
        var result = await daprClient.InvokeMethodAsync<ApiResult>(request2);
        return Ok(result);
    }
}

public class RoleResourcePageQuery
{
    public required string Service { get; set; } = "";
    public PageQuery<PageResult<RoleResourceOutDto>> Query { get; set; } = new();
}

public class SetRoleResourceRequest
{
    public long RoleId { get; set; }
    public Dictionary<string, RoleResourceDto[]> Dict { get; set; } = new();
}

public class SetFilterGroupsRequest
{
    public string Service { get; set; } = "";
    public string ResourceId { get; set; } = "";
    public string RoleId { get; set; } = "";
    public Dictionary<string, FilterGroup> FilterGroups { get; set; } = new();
}

public class RoleResourceDto
{
    public long ResourceId { get; set; }
    public string[] Operations { get; set; } = [];
}

public class RoleResourceOutDto
{
    public long Id { get; set; }
    public long RoleId { get; set; }
    public long ResourceId { get; set; }
    public required string ResourceName { get; set; }
    public required string ResourceCode { get; set; }
    public string[] Operations { get; set; } = [];
    public ResourceOperation[] AllowedOperations { get; set; } = [];
    public Dictionary<string, FilterGroup> FilterGroups { get; set; } = [];
    public EntityMetadata? EntityMetadata { get; set; }
    public DateTime CreatedTime { get; set; }
    public bool IsLocked { get; set; }
}
